﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Log4Net;

namespace PollServer
{
    public class Connetion
    {
        public MySQLDBConnetion _conn;

        public Connetion(MySQLDBConnetion conn)
        {
            _conn = conn;
        }
    }

    /// <summary>
    /// 数据库连接池
    /// 不默认创建DB连接
    /// </summary>
    public class DbPool
    {
        //用一个链表进行数据库连接的容器，
        private Dictionary<string, Queue<Connetion>> coonPool = new Dictionary<string, Queue<Connetion>>();

        //数据库连接池中的最大负荷
        private int connectionMax = 40;
        //当前连接数
        private int currentCount = 0;
        private object _lock = new object();

        public DbPool()
        {

        }

        /**
        * 创建一个connection对象
        * @return 和数据库进行连接的connection对象，异常的时候是一个null
        */
        private MySQLDBConnetion createConnection(string serverip, string account, string password, string dbname, string port)
        {
            MySQLDBConnetion conn = null;
            try 
            {
                conn = new MySQLDBConnetion(serverip, account, password, dbname, port);
            }
            catch(Exception err)
            {
                LogHelper.WriteLog("创建SQL连接时" + dbname, err);
            }
            return conn;
        }

        /**
        * 从池中获取对象的操作
        * @return 表的第一个元素
        *加锁的处理，保证不同的线程在去连接的时候拿到的连接是不同的
        */
        public MySQLDBConnetion getConnection(string serverip, string account, string password, string dbname, string port) 
        {
            MySQLDBConnetion conn = null;
            lock(_lock)
            {
                if (coonPool.ContainsKey(dbname))
                {
                    Queue<Connetion> tmp = coonPool[dbname];
                    if (tmp.Count > 0)
                    {
                        Connetion cnn = tmp.Dequeue();
                        conn = cnn._conn;
                    }
                    else
                    {
                        if (currentCount < connectionMax){
                            conn = createConnection(serverip, account, password, dbname, port);
                            if (conn != null){
                                currentCount++;
                            }
                        }
                        else{
                            LogHelper.WriteLog("获取DB连接时", new Exception("没有空闲的连接对象"));
                        }
                    }
                }
                else
                {
                     if (currentCount < connectionMax){
                        conn = createConnection(serverip, account, password, dbname, port);
                        if (conn != null){
                            currentCount++;
                         }
                    }
                    else{
                        LogHelper.WriteLog("获取DB连接时", new Exception("没有空闲的连接对象"));
                    }
                }
            }
            return conn;
        }  
		/**
		* 释放时候的操作就是把连接的对象放置在链表的末尾的操作
		* @param conn 使用完毕的connection对象
		*/
        public void free(MySQLDBConnetion conn)
        {
            string dbname = conn.dbname;
            if (coonPool.ContainsKey(dbname))
            {
                Queue<Connetion> tmp = coonPool[dbname];
                Connetion cnn = new Connetion(conn);
                tmp.Enqueue(cnn);
            }
            else
            {
                Queue<Connetion> tmp = new Queue<Connetion>();
                Connetion cnn = new Connetion(conn);
                tmp.Enqueue(cnn);
                coonPool.Add(dbname, tmp);
            }
		}
    };
}
